package controller

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"os"
	"os/exec"
	"path/filepath"
	"service/components"
	"service/constant"
	"service/modules"
	"service/utils"
	"strconv"
	"strings"
	"time"

	"github.com/spf13/viper"

	"github.com/gin-gonic/gin"
)

// SavePictureController 上传单个文件
func SavePictureController(ctx *gin.Context) {
	file, err := ctx.FormFile("file")
	authorization := ctx.GetHeader("authorization")
	fmt.Println("authorization", authorization)
	_t := ctx.PostForm("type")
	if err != nil {
		utils.HandleFailResponse(ctx, "ERROR： 系统错误 "+err.Error(), nil)
		return
	}
	if !strings.ContainsAny(ctx.Request.Host, "120.79.36.108") {
		utils.HandleFailResponse(ctx, "权限不够!!", nil)
		return
	}
	admin := viper.GetString("origin.admin")
	localhost := viper.GetString("origin.localhost")
	//权限控制
	flag := false
	origin := ctx.GetHeader("origin")
	fmt.Println("=>  origin  ", origin)
	if origin == admin {
		flag = true
	}
	if origin == localhost {
		flag = true
	}
	if !flag {
		fmt.Println("flag: => ", flag, origin)
		utils.HandleFailResponse(ctx, "上传文件权限不够!!", nil)
		return
	}
	// 文件打开
	f, _ := file.Open()
	defer func(f multipart.File) {
		err := f.Close()
		if err != nil {

		}
	}(f)
	// 生成唯一标识
	myUUID := utils.GenerateUUID(fmt.Sprintf("%d", file.Size) + file.Filename)
	// 查询是否已有该图片
	c, _ := modules.GetFileByUUIDService(myUUID)
	if len(c) != 0 {
		url := ""
		for i, value := range c {
			if !utils.IsImage(value.Url) {
				continue
			}
			if utils.IsImage(value.Url) {
				if i > len(c)-1 {
					url += value.Url
				} else {
					url += value.Url + ","
				}
			}
		}
		utils.HandleSuccessResponse(ctx, "文件已上传，请勿上传", gin.H{
			"url":       url,
			"file_name": file.Filename,
			"size":      file.Size,
			"uuid":      myUUID,
		})
		return
	}
	// 切割文件名
	endNames := strings.Split(file.Filename, ".")
	str := ""
	// 拿到文件的后缀名
	endName := endNames[len(endNames)-1]
	// 图片
	if utils.IsImage(file.Filename) {
		// 拼接保存文件的路径
		str = fmt.Sprintf("uploads/%s.%s", myUUID, endName)
		// 打开本地的文件
		out, err := os.Create(str)
		if err != nil {
			utils.HandleFailResponse(ctx, "创建文件失败", nil)
			return
		}
		defer func(out *os.File) {
			err := out.Close()
			if err != nil {

			}
		}(out)
		// 复制上传的文件覆盖本地的文件
		_, err = io.Copy(out, f)
		if err != nil {
			utils.HandleFailResponse(ctx, "创建文件失败", nil)
			return
		}
		file_ := modules.File{
			Url:       utils.FileUrl + str,
			Type:      _t,
			FileName:  file.Filename,
			UUID:      myUUID,
			Attribute: "全部",
			CreateAt:  time.Now(),
		}
		err = modules.AddFilePictureService(&file_)
		if err != nil {
			utils.HandleFailResponse(ctx, "文件上传失败~", nil)
			return
		}
		utils.HandleSuccessResponse(ctx, "文件上传成功!", gin.H{
			"url":       utils.FileUrl + str,
			"file_name": file.Filename,
			"size":      file.Size,
			"uuid":      myUUID,
		})
		return
	} else if endName == "pdf" {
		str = fmt.Sprintf("uploads/%s", myUUID)
		//保存PDF
		out, err := os.Create(str + ".pdf")
		if err != nil {
			utils.HandleFailResponse(ctx, "创建文件失败", nil)
			return
		}
		defer func(out *os.File) {
			err := out.Close()
			if err != nil {

			}
		}(out)
		// 复制上传的文件覆盖本地的文件
		_, err = io.Copy(out, f)
		if err != nil {
			utils.HandleFailResponse(ctx, "创建文件失败", nil)
			return
		}
		file_ := modules.File{
			Url:       utils.FileUrl + str + ".pdf",
			Type:      endName,
			FileName:  file.Filename,
			UUID:      myUUID,
			Attribute: "全部",
			CreateAt:  time.Now(),
		}
		err = modules.AddFilePictureService(&file_)
		if err != nil {
			utils.HandleFailResponse(ctx, "文件上传失败~", nil)
			return
		}
		// 保存图片
		cmd := exec.Command("pdftoppm", "-jpeg", "-y", strconv.Itoa(30), "-H", strconv.Itoa(1550), str+".pdf", str)
		err = cmd.Run()
		if err != nil {
			fmt.Println("Error:", err)
			utils.HandleFailResponse(ctx, "pdf转图片失败", nil)
			return
		}
		pdfUrl := ""
		files, err := filepath.Glob("uploads/" + myUUID + "*")
		for i, file1 := range files {
			s := strings.Replace(file1, "\\", "/", 5)
			if utils.IsImage(file1) {
				if i > len(files)-1 {
					pdfUrl += utils.FileUrl + s
				} else {
					pdfUrl += utils.FileUrl + s + ","

				}
				url := utils.FileUrl + s
				file_ = modules.File{
					Url:       url,
					Type:      endName,
					FileName:  file.Filename,
					UUID:      myUUID,
					Attribute: "全部",
					CreateAt:  time.Now(),
				}
				err = modules.AddFilePictureService(&file_)
				if err != nil {
					utils.HandleFailResponse(ctx, "图片上传失败~", nil)
					return
				}
			}
		}
		if err != nil {
			log.Fatal(err)
		}
		utils.HandleSuccessResponse(ctx, "上传图片成功", gin.H{
			"url":       pdfUrl,
			"file_name": file.Filename,
			"size":      file.Size,
			"uuid":      myUUID,
		})
	} else if utils.IsVideo(file.Filename) {
		// 拼接保存文件的路径
		str = fmt.Sprintf("uploads/%s.%s", myUUID, endName)
		// 打开本地的文件
		out, err := os.Create(str)
		if err != nil {
			utils.HandleFailResponse(ctx, "创建文件失败", nil)
			return
		}
		defer func(out *os.File) {
			err := out.Close()
			if err != nil {

			}
		}(out)
		// 复制上传的文件覆盖本地的文件
		_, err = io.Copy(out, f)
		if err != nil {
			utils.HandleFailResponse(ctx, "创建文件失败", nil)
			return
		}

		file_ := modules.File{
			Url:       utils.FileUrl + str,
			Type:      "video",
			FileName:  file.Filename,
			UUID:      myUUID,
			Attribute: "全部",
			CreateAt:  time.Now(),
		}
		err = modules.AddFilePictureService(&file_)
		if err != nil {
			utils.HandleFailResponse(ctx, "文件上传失败~", nil)
			return
		}
		fmt.Println("上传视频到抖音等......   3 ")
		utils.HandleSuccessResponse(ctx, "文件上传成功", gin.H{
			"url":       utils.FileUrl + str,
			"file_name": file.Filename,
			"size":      file.Size,
			"uuid":      myUUID,
		})
	}

}

// SavePicturesController 上传多个图片
func SavePicturesController(ctx *gin.Context) {
	files, err := ctx.MultipartForm()
	if err != nil {
		fmt.Println("多个文件")
		return
	}
	if !strings.ContainsAny(ctx.Request.Host, "120.79.36.108") {
		utils.HandleFailResponse(ctx, "权限不够!", nil)
		return
	}
	admin := viper.GetString("origin.admin")
	localhost := viper.GetString("origin.localhost")
	// 权限控制
	flag := false
	origin := ctx.GetHeader("origin")
	if origin == admin {
		flag = true
	}
	if origin == localhost {
		flag = true
	}
	if !flag {
		utils.HandleFailResponse(ctx, "上传文件权限不够!!", nil)
		return
	}
	var fileArr []string

	for _, file := range files.File["files"] {
		// 切割文件名
		endNames := strings.Split(file.Filename, ".")
		// 拿到文件的后缀名
		endName := endNames[len(endNames)-1]
		myUUID := utils.GenerateUUID(fmt.Sprintf("%d", file.Size) + file.Filename)
		c, _ := modules.GetFileByUUIDService(myUUID)
		str := fmt.Sprintf("uploads/%s.%s", myUUID, endName)
		if len(c) != 0 {
			utils.HandleSuccessResponse(ctx, "该图片已上传，请勿上传", gin.H{
				"url": c[0].Url,
			})
			return
		}
		err = SaveFileController(file, str)
		if err != nil {
			utils.HandleFailResponse(ctx, "文件生成失败", err.Error())
			return
		}
		file_ := modules.File{
			Url:       utils.FileUrl + str,
			Type:      "jpg",
			FileName:  file.Filename,
			UUID:      myUUID,
			Attribute: "全部",
			CreateAt:  time.Now(),
		}
		fileArr = append(fileArr, utils.FileUrl+str)
		err = modules.AddFilePictureService(&file_)
		if err != nil {
			utils.HandleFailResponse(ctx, "图片上传失败~", nil)
			return
		}

	}

	utils.HandleSuccessResponse(ctx, "图片上传成功", gin.H{
		"images": fileArr,
	})
}

// GetAllPicsController 获取文件列表
func GetAllPicsController(ctx *gin.Context) {
	files, total := modules.GetAllPicsService()
	utils.HandleSuccessResponse(ctx, "查询成功", gin.H{
		"total":  total,
		"images": files,
	})
}

// GetFileController 获取文件列表
func GetFileController(ctx *gin.Context) {
	query := ctx.DefaultQuery("type", "jpg")
	attr := ctx.DefaultQuery("attribute", "全部")
	fileName := ctx.Query("file_name")
	db := components.DB.Model(modules.File{}).Order("id desc")
	pagination := constant.Pagination{}
	err := ctx.ShouldBind(&pagination)
	if err != nil {
		return
	}
	files := make([]modules.File, 20)
	// 查找详情
	if fileName != "" {
		file := &modules.File{}
		err := db.Where("file_name = ? AND type = ?", fileName, query).First(&file).Error
		if err != nil {
			utils.HandleFailResponse(ctx, "没有该文件", nil)
			return
		}
		utils.HandleSuccessResponse(ctx, "获取文件详情", file)
		return
	}
	//var count int64 = 0
	//if query == "jpg" && attr == "全部" {
	//	db = db.Where("type = ?", query)
	//	count = db.Find(&files).RowsAffected
	//} else if query == "video" && attr == "全部" {
	//	db = db.Where("type = ?", query)
	//	count = db.Find(&files).RowsAffected
	//} else if query == "pdf" && attr == "全部" {
	//	db = db.Where("type = ?", query)
	//	count = db.Find(&files).RowsAffected
	//} else {
	//	db = db.Where("type = ? AND attribute = ? ", query, attr)
	//}
	db = db.Where("type = ? AND attribute = ? ", query, attr)
	count := db.Find(&files).RowsAffected
	fmt.Println("查询所有的东西 => ", count, query, attr, fileName)
	if pagination.Limit != 0 {
		db = db.Limit(pagination.Limit).Offset(pagination.Offset)
	}
	db.Find(&files)
	utils.HandleSuccessResponse(ctx, "获取成功", gin.H{
		"total": count,
		"list":  files,
	})
}

// UpdateFileController 更新文件信息
func UpdateFileController(ctx *gin.Context) {
	myData := struct {
		Arr       string `json:"arr"`
		Attribute string `json:"attribute"`
	}{}
	err := ctx.ShouldBindJSON(&myData)
	if err != nil {
		utils.HandleFailResponse(ctx, "文件移动失败", nil)
		return
	}

	str := fmt.Sprintf("id IN (%s)", myData.Arr)
	components.DB.Model(modules.File{}).Where(str).Update("attribute", myData.Attribute)
	utils.HandleSuccessResponse(ctx, "文件移动成功", nil)
}

// UpdateFileInfoController 更新文件信息
func UpdateFileInfoController(ctx *gin.Context) {
	file := &modules.File{}
	err := ctx.ShouldBindJSON(&file)
	if err != nil {
		utils.HandleFailResponse(ctx, "文件修改失败", nil)
		return
	}
	components.DB.Table("file").
		Where("id = ?", file.Id).
		First(&modules.File{}).
		Updates(&file)
	utils.HandleSuccessResponse(ctx, "文件修改成功", nil)
}

// DeleteFileController 删除文件
func DeleteFileController(ctx *gin.Context) {
	raw, _ := ctx.GetRawData()
	data := make(map[string]string, 10)
	err := json.Unmarshal(raw, &data)
	if err != nil {
		utils.HandleFailResponse(ctx, "数据绑定失败", nil)
		return
	}
	// 得到uuid数组
	uuid := strings.Split(data["uuid"], ",")
	// 为空则没有选择文件
	if data["id"] == "" || data["uuid"] == "" {
		utils.HandleFailResponse(ctx, "请选择需要删除的文件!", nil)
		return
	}
	for _, v := range uuid {
		// 删除数据库文件
		err := components.DB.
			Where("uuid = ?", v).
			Find(&modules.File{}).
			Delete(&modules.File{}).Error
		if err != nil {
			utils.HandleFailResponse(ctx, "文件删除失败", nil)
			return
		}
		// 查找本地文件相同的名字 返回数组
		files, _ := filepath.Glob("uploads/" + v + "*")
		for _, File := range files {
			err := os.Remove(File)
			if err != nil {
				utils.HandleFailResponse(ctx, "删除文件失败", nil)
				return
			}
		}
	}
	utils.HandleSuccessResponse(ctx, "删除文件成功", nil)

}

func SaveFileController(file *multipart.FileHeader, middlePath string) error {
	createPath, err := os.Create(middlePath)
	if err != nil {
		return err
	}
	openFile, err := file.Open()
	if err != nil {
		return err
	}
	defer func(openFile multipart.File) {
		_ = openFile.Close()
	}(openFile)
	// 把上传的文件保存到服务器
	_, err = io.Copy(createPath, openFile)
	return err
}
